#include "gpio.h"

gpio_struct gpio_str(gpio_enum gpio_e);
/**
 * @brief 启用GPIO
 * 
 * @param e_gpio 哪个GPIO
 * @param mode 模式 （GPIO_MODE_INPUT、GPIO_MODE_OUTPUT 或 GPIO_MODE_ANALOG）
 * @param pull_up_down 上拉下拉 （GPIO_PUPD_NONE、GPIO_PUPD_PULLUP 或 GPIO_PUPD_PULLDOWN）
 */
void gpio_enable_pull(gpio_enum e_gpio, uint32_t mode, uint32_t pull_up_down){
    gpio_struct gpio_s = gpio_str(e_gpio);
    /* enable the GPIO clock */
    rcu_periph_clock_enable(gpio_s.rcu_periph);
    /* configure GPIO port */ 
    if(GPIO_MODE_OUTPUT == mode){
        gpio_mode_set(gpio_s.gpio_periph, mode, GPIO_PUPD_NONE, gpio_s.pin);
        gpio_output_options_set(gpio_s.gpio_periph, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gpio_s.pin);
    }else if (GPIO_MODE_INPUT == mode){
        gpio_mode_set(gpio_s.gpio_periph, mode, pull_up_down, gpio_s.pin);
    }else if (GPIO_MODE_ANALOG == mode){
        gpio_mode_set(gpio_s.gpio_periph, mode, GPIO_PUPD_NONE, gpio_s.pin);
    }
    
}

/**
 * @brief 启用GPIO的AF
 * 
 * @param e_gpio 哪个GPIO
 * @param alt_func_num eg:GPIO_AF_0
 */
void gpio_enable_AF(gpio_enum e_gpio, uint32_t alt_func_num){
    gpio_struct gpio_s = gpio_str(e_gpio);
    gpio_mode_set(gpio_s.gpio_periph, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_s.pin);
    gpio_output_options_set(gpio_s.gpio_periph, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gpio_s.pin);
    gpio_af_set(gpio_s.gpio_periph, alt_func_num, gpio_s.pin);
}

/**
 * @brief 启用GPIO
 * 
 * @param e_gpio 哪个GPIO
 * @param mode 模式 （GPIO_MODE_INPUT、GPIO_MODE_OUTPUT 或 GPIO_MODE_AF）
 */
void gpio_enable(gpio_enum e_gpio, uint32_t mode){
    gpio_enable_pull(e_gpio, mode, GPIO_PUPD_NONE);
}

/**
 * @brief 写GPIO
 * 
 * @param e_gpio 哪个GPIO
 * @param val 值（0 或 1）
 */
void gpio_write(gpio_enum e_gpio, uint8_t val){
    gpio_struct gpio_s = gpio_str(e_gpio);
    if(val){
        gpio_bit_set(gpio_s.gpio_periph, gpio_s.pin);
    }else{
        gpio_bit_reset(gpio_s.gpio_periph, gpio_s.pin);
    }
}

/**
 * @brief 读GPIO
 * 
 * @param e_gpio 哪个GPIO
 * @return uint8_t 
 */
uint8_t gpio_read(gpio_enum e_gpio){
    gpio_struct gpio_s = gpio_str(e_gpio);
    return (SET == gpio_input_bit_get(gpio_s.gpio_periph, gpio_s.pin));
}


gpio_struct gpio_str(gpio_enum gpio_e){
    rcu_periph_enum rcu_periph = RCU_GPIOA;
    uint32_t gpio_periph = GPIOA;
    uint32_t pin = GPIO_PIN_0;
    switch (gpio_e)
    {
    case GA0:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_0;
        break;
    case GA1:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_1;
        break;
    case GA2:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_2;
        break;
    case GA3:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_3;
        break;
    case GA4:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_4;
        break;
    case GA5:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_5;
        break;
    case GA6:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_6;
        break;
    case GA7:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_7;
        break;
    case GA8:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_8;
        break;
    case GA9:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_9;
        break;
    case GA10:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_10;
        break;
    case GA11:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_11;
        break;
    case GA12:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_12;
        break;
    case GA13:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_13;
        break;
    case GA14:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_14;
        break;
    case GA15:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_15;
        break;
    case GAALL:
        rcu_periph = RCU_GPIOA;
        gpio_periph = GPIOA;
        pin = GPIO_PIN_ALL;
        break;
    
    case GB0:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_0;
        break;
    case GB1:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_1;
        break;
    case GB2:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_2;
        break;
    case GB3:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_3;
        break;
    case GB4:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_4;
        break;
    case GB5:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_5;
        break;
    case GB6:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_6;
        break;
    case GB7:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_7;
        break;
    case GB8:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_8;
        break;
    case GB9:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_9;
        break;
    case GB10:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_10;
        break;
    case GB11:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_11;
        break;
    case GB12:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_12;
        break;
    case GB13:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_13;
        break;
    case GB14:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_14;
        break;
    case GB15:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_15;
        break;
    case GBALL:
        rcu_periph = RCU_GPIOB;
        gpio_periph = GPIOB;
        pin = GPIO_PIN_ALL;
        break;

    case GC0:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_0;
        break;
    case GC1:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_1;
        break;
    case GC2:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_2;
        break;
    case GC3:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_3;
        break;
    case GC4:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_4;
        break;
    case GC5:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_5;
        break;
    case GC6:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_6;
        break;
    case GC7:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_7;
        break;
    case GC8:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_8;
        break;
    case GC9:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_9;
        break;
    case GC10:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_10;
        break;
    case GC11:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_11;
        break;
    case GC12:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_12;
        break;
    case GC13:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_13;
        break;
    case GC14:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_14;
        break;
    case GC15:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_15;
        break;
    case GCALL:
        rcu_periph = RCU_GPIOC;
        gpio_periph = GPIOC;
        pin = GPIO_PIN_ALL;
        break;

    case GD0:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_0;
        break;
    case GD1:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_1;
        break;
    case GD2:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_2;
        break;
    case GD3:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_3;
        break;
    case GD4:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_4;
        break;
    case GD5:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_5;
        break;
    case GD6:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_6;
        break;
    case GD7:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_7;
        break;
    case GD8:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_8;
        break;
    case GD9:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_9;
        break;
    case GD10:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_10;
        break;
    case GD11:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_11;
        break;
    case GD12:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_12;
        break;
    case GD13:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_13;
        break;
    case GD14:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_14;
        break;
    case GD15:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_15;
        break;
    case GDALL:
        rcu_periph = RCU_GPIOD;
        gpio_periph = GPIOD;
        pin = GPIO_PIN_ALL;
        break;

    case GF0:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_0;
        break;
    case GF1:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_1;
        break;
    case GF2:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_2;
        break;
    case GF3:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_3;
        break;
    case GF4:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_4;
        break;
    case GF5:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_5;
        break;
    case GF6:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_6;
        break;
    case GF7:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_7;
        break;
    case GF8:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_8;
        break;
    case GF9:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_9;
        break;
    case GF10:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_10;
        break;
    case GF11:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_11;
        break;
    case GF12:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_12;
        break;
    case GF13:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_13;
        break;
    case GF14:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_14;
        break;
    case GF15:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_15;
        break;
    case GFALL:
        rcu_periph = RCU_GPIOF;
        gpio_periph = GPIOF;
        pin = GPIO_PIN_ALL;
        break;

    default:
        break;
    }
    gpio_struct gpio = {rcu_periph, gpio_periph, pin};
    return gpio;
}
